import os
from datetime import datetime
import pandas as pd

from base.constant import out_folder
from base.util.time_util import time_to_seconds, seconds_to_time


def population_sampling(config_yaml):
    session_id_file = f"{out_folder}{os.sep}{config_yaml['session']['time_session_out']}"
    sample_rate = config_yaml['sample']['sample_rate']
    if not os.path.exists(session_id_file):
        print(f"{session_id_file} file not found")
        exit(0)
    df = pd.read_csv(session_id_file, delimiter=',')
    df = df.fillna("")
    json_data = df.to_dict(orient='records')
    print("读取完毕,开始解析")
    print(f"session_id文件中的数量：{len(json_data)}")
    if sample_rate == 1:
        print(f"总体抽样，抽样率:{sample_rate}，均匀抽出{len(json_data)}条数据")
        return json_data
    sample_size = round(sample_rate * len(json_data))
    step = len(json_data) / sample_size
    sampled_data = [json_data[int(i * step)] for i in range(sample_size)]
    print(f"总体抽样，抽样率:{sample_rate}，均匀抽出{len(sampled_data)}条数据")
    return sampled_data


def is_excluded_time(datetime_obj, excluded_dates, excluded_weekly_occurrence):
    if datetime_obj.date() in excluded_dates:
        return True
    if datetime_obj.weekday() + 1 in excluded_weekly_occurrence:
        return True
    return False


def fill_time_gaps(time_rate, other_rate):
    time_rate1 = []
    for t in time_rate:
        time_rate1.append([time_to_seconds(t[0]), time_to_seconds(t[1]), t[2]])
    complete_time_rate = []
    last_end = -1  # 初始化为-1
    for t in time_rate1:
        start = t[0]
        end = t[1]
        if start > last_end + 1:  # 检查是否有缺失区间
            complete_time_rate.append([last_end + 1, start - 1])
        complete_time_rate.append([start, end, t[2]])
        last_end = end
    if last_end < 86399:
        complete_time_rate.append([last_end + 1, 86399])
    for t in complete_time_rate:
        t[0] = seconds_to_time(t[0])
        t[1] = seconds_to_time(t[1])
    # rate = 1 - sum([t[2] for t in complete_time_rate if len(t) == 3])
    length_is_tow = [t for t in complete_time_rate if len(t) == 2]
    # other_rate = round(rate / len(length_is_tow), 3)
    for t in length_is_tow:
        t.append(other_rate)
    return complete_time_rate


def extract_time_from_datetime(t):
    return t.time()


def is_within_workday(time_to_check, workday_start, workday_end):
    # 检查时间是否处于工作时间范围内
    if workday_start <= time_to_check <= workday_end:
        return True
    else:
        return False


def get_date_in_array(data, workday_rate):
    within_list = []
    rate_start = datetime.strptime(workday_rate[0], "%H:%M:%S")
    rate_end = datetime.strptime(workday_rate[1], "%H:%M:%S")
    rss = rate_start.hour * 3600 + rate_start.minute * 60 + rate_start.second
    res = rate_end.hour * 3600 + rate_end.minute * 60 + rate_end.second
    for item in data:
        firstPacket = datetime.fromtimestamp(item["firstPacket"]/1000)
        fs = firstPacket.hour * 3600 + firstPacket.minute * 60 + firstPacket.second
        if rss <= fs <= res:
            within_list.append(item)
    return within_list


def data_sample(data, param_from_yaml, time_threshold, other_rate):
    all_sample = []
    workday_rate_array = fill_time_gaps(time_rate=param_from_yaml, other_rate=other_rate)
    for workday_rate in workday_rate_array:
        # 获取属于本时段的data
        time_sample = get_date_in_array(data, workday_rate)
        # print(f"处于{workday_rate}的有{len(time_sample)}个")
        if len(time_sample) <= time_threshold:
            # print(f"本时间段落少于{time_threshold}，默认全取")
            all_sample.extend(time_sample)
        else:
            # print("开始按比例抽样")
            sample_size = round(workday_rate[2] * len(time_sample))
            # print(f"日期抽样，抽样率:{workday_rate[2]}，均匀抽出{sample_size}条数据")
            step = len(time_sample) / sample_size
            sampled_data = [time_sample[int(i * step)] for i in range(sample_size)]
            all_sample.extend(sampled_data)
    return all_sample


def filter_excluded_data(sample, excluded_data):
    non_excluded_data = [data for data in sample if data not in excluded_data]
    return non_excluded_data


def is_not_excluded(data, excluded_data):
    return data not in excluded_data


def sample_by_day(sample, config_yaml):
    excluded_dates = config_yaml['sample']['time_in_holiday']['dates']
    excluded_weekly_occurrence = config_yaml['sample']['time_in_holiday']['weekly_occurrence']
    excluded_data = [
        data for data in sample if
        is_excluded_time(datetime.fromtimestamp(data["firstPacket"]/1000), excluded_dates, excluded_weekly_occurrence) or is_excluded_time(
            datetime.fromtimestamp(data["lastPacket"]/1000), excluded_dates, excluded_weekly_occurrence)
    ]
    non_excluded_data = [
        data for data in sample if
        not is_excluded_time(datetime.fromtimestamp(data["firstPacket"]/1000), excluded_dates, excluded_weekly_occurrence) and not is_excluded_time(
            datetime.fromtimestamp(data["lastPacket"]/1000), excluded_dates, excluded_weekly_occurrence)
    ]
    time_rate_in_workday = config_yaml['sample']['time_rate_in_workday']
    time_rate_in_holiday = config_yaml['sample']['time_in_holiday']['time_rate_in_holiday']
    other_rate = config_yaml['sample']['other_rate']
    time_threshold = config_yaml['sample']['threshold']
    res_excluded_sample_data = data_sample(excluded_data, param_from_yaml=time_rate_in_workday,
                                           time_threshold=time_threshold, other_rate=other_rate)
    res_workday_sample_data = data_sample(non_excluded_data, param_from_yaml=time_rate_in_holiday,
                                          time_threshold=time_threshold, other_rate=other_rate)
    result = [*res_excluded_sample_data, *res_workday_sample_data]
    print(f"日期抽样：节假日抽样率{time_rate_in_holiday},工作日抽样率{time_rate_in_workday},共抽出{len(result)}条数据")
    return result


def handle_sample(config_yaml):
    print("正在抽样...")
    sample = population_sampling(config_yaml)
    sample = sample_by_day(sample, config_yaml)
    print(f"抽样完毕：{len(sample)}")
    return sample
